package code.example.base.util.concurrent.lock.waitnotify;


import code.example.tool.LogFactory;

/**
 *  wait方法调用后，线程进入阻塞状态，由其它线程调用notify 或 notifyAll唤醒后，获得cpu时间片，进入执行状态，
 *  wait方法----》线程进入监控器waitSet队列--》其它线程调用notify 或 notifyAll--》进入entryList队列--》锁被释放--》
 *  可能被唤醒--》可运行状态--》得以cpu时间片--》运行状态--》可能获得锁--》从wait之后的代码开始执行。
 *
 *  wait方法之前，取得的变量，可能已经被其它线程修改了，为了确保正确性，wait之后重新取值计算。
 */
public class WaitTest {

    int count = 0;
    public synchronized  void toWait() throws InterruptedException{
        int data = count;
        data++;
        LogFactory.getLog().info("first time count:"+count);
        LogFactory.getLog().info("first time data:"+data);
        LogFactory.getLog().info("to waiting .....");
        this.wait();
        LogFactory.getLog().info("wake up!");
        data++;
        LogFactory.getLog().info("second time count:"+count);
        LogFactory.getLog().info("second time data:"+data);
    }
    public synchronized  void toNotify() throws  InterruptedException{
        count = 1000;
        this.notify();
    }

    public static void main(String args []){
       final WaitTest waitTest = new WaitTest();
        Thread waitThread =   new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    waitTest.toWait();
                }catch (Exception  ee){};
            }
        });
        Thread notifyThead = new  Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    waitTest.toNotify();
                }catch (Exception  ee){};
            }
        });
        waitThread.start();
        try {
            Thread.sleep(1000);
        }catch (Exception e){};
        notifyThead.start();
    }
}
